Jova Solutions
Application Note
Jova_AN-01

USB Interface Protocol for Jova Products


Website References:
FTDI
Calling FTD2XX.DLL from Visual Basic
http://www.ftdichip.com/Projects/CodeExamples/VB.htm
File:	D2XX_Unit_NET.vb



Reference Documents:
Jova Solutions:
 
Jova FTDI with Visual Basic

Reference file:	D2XX_Unit_NET.vb

There are a few procedures to be performed in order to access the FTDI USB device. 

The function calls, variables and name constants are defined in FTDIs file: D2XX_Unit_NET.vb

The Pseudo-Code below identifies the necessary variable, constants and functions to perform within each procedure. 

The procedure lists only some of the possible error handling for the given example.





    //---- Jova Protocol Data Unit (PDU) Packet Definitions ----

    Public Const PDU_Data_Size = 1024
    Public Const PDU_Data_Index = PDU_Data_Size  1


    Public Structure PDU_Packet
        Dim PDU_To As Byte
        Dim PDU_From As Byte
        Dim PDU_Control As Short
        Dim PDU_Status As Short
        Dim PDU_Ref As Byte
        Dim PDU_Data_Length As Byte
        Dim PDU_Data(PDU_Data_Index) As Byte	
    End Structure


    Public RX_PDU_Packet As PDU_Packet
    Public TX_PDU_Packet As PDU_Packet


 
    //---- Jova Remote Terminal Unit (RTU) Buffer Definitions ----

    Public Const RX_Residual_Buffer_Size = 1024
    Public Const RX_Residual_Buffer_Index = RX_Residual_Buffer_Size - 1

    Public RX_Residual_Buffer(RX_Residual_Buffer_Index)


    '// Note: RTU_Buffer_Size = 265 = Header(8 bytes) + Data(256 bytes max) + LRC(1 Byte)

    Public Const RX_RTU_Buffer_Size = 265
    Public Const RX_RTU_Buffer_Index = RX_RTU_Buffer_Size - 1

    Public RX_RTU_Buffer(RX_RTU_Buffer_Index) As Byte


    Public Const TX_RTU_Buffer_Size = 265
    Public Const TX_RTU_Buffer_Index = TX_RTU_Buffer_Size - 1

    Public TX_RTU_Buffer(TX_RTU_Buffer_Index) As Byte


    Public Const RTU_To_Index = 0
    Public Const RTU_From_Index = 1
    Public Const RTU_Control_MSB_Index = 2
    Public Const RTU_Control_LSB_Index = 3
    Public Const RTU_Status_MSB_Index = 4
    Public Const RTU_Status_LSB_Index = 5
    Public Const RTU_Ref_Index = 6
    Public Const RTU_Data_Length_Index = 7
    Public Const RTU_Data_Index = 8
 

    '//---- Jova Working Variables ----

    Public TX_RTU_LRC As Byte

    Public RX_RTU_LRC As Byte
    Public RX_PDU_LRC As Byte
    







    '//-----------------------------------------------------------------------------------
    '//    Procedure (1): TIMS_DEVICE_OPEN
    '//-----------------------------------------------------------------------------------
    '//    This example procedure will open the first FTDI USB device by index
    '//
    '//    Note: Modify this procedure if multiple FTDI devices exist.
    '//

    Function TIMS_DEVICE_OPEN()

    '//----(1.1): Verify an FTDI USB device is attached (presuming a TIMS-xxxx)

        GetFTDeviceCount()		//	value returned to FT_Device_Count

        If FT_Status <> FT_OK Then
            '-- add error reporting here
            Exit Function
        End If

	If (FT_Device_Count = 0) Then
            '-- add error reporting here
            Exit Function
	END IF


    '//----(1.2): Open handle to 1st FTDI USB device by index

	DeviceIndex = 0
	Open_USB_Device_By_Index(DeviceIndex)

        If FT_Status <> FT_OK Then
            '-- add error reporting here
            Exit Function
        End If


    '//----(1.3): Initialize communications configuration

        Reset_USB_Device()

            If FT_Status <> FT_OK Then
                '-- add error reporting here
                Exit Function
            End If


        FT_Current_DataBits = FT_DATA_BITS_8
        FT_Current_StopBits = FT_STOP_BITS_1
        FT_Current_Parity = FT_PARITY_NONE
        Set_USB_Device_Data_Characteristics()

            If FT_Status <> FT_OK Then
                '-- add error reporting here
                Exit Function
            End If


        FT_Current_Baud = FT_BAUD_230400
        Set_USB_Device_Baud_Rate()
 
            If FT_Status <> FT_OK Then
                '-- add error reporting here
                Exit Function
            End If


        ReadTimeOut = 10000			// 10 sec
        WriteTimeOut = 10000			// 10 sec
        Set_USB_Device_Timeouts(ReadTimeOut,WriteTimeOut)

            If FT_Status <> FT_OK Then
                '-- add error reporting here
                Exit Function
            End If


        FT_Latency = 1				// 1 ms
        Set_USB_Device_Latency()

            If FT_Status <> FT_OK Then
                '-- add error reporting here
                Exit Function
            End If


        Purge_USB_Device_In()

            If FT_Status <> FT_OK Then
                '-- add error reporting here
                Exit Function
            End If

    End Function
    '//---------------------------------------------------------------------------------



    '// Packet <--> Buffer Conversions


    '//-----------------------------------------------------------------------------------
    '//    Procedure (2): TX Packet --> TX Buffer
    '//-----------------------------------------------------------------------------------

    Function Cast_TX_PDU_Packet_to_TX_RTU_Buffer()

        Dim RTU_Index As Integer
        Dim Data_Index As Integer
	Dim Count As Integer

    '//----(2.1): Copy fixed length variables

        TX_RTU_Buffer(RTU_To_Index) = TX_PDU_Packet.PDU_To
        TX_RTU_Buffer(RTU_From_Index) = TX_PDU_Packet.PDU_From
        TX_RTU_Buffer(RTU_Control_MSB_Index) = TX_PDU_Packet.PDU_Control / 256
        TX_RTU_Buffer(RTU_Control_LSB_Index) = TX_PDU_Packet.PDU_Control 'AND' &HFF
        TX_RTU_Buffer(RTU_Status_MSB_Index) = TX_PDU_Packet.PDU_Status / 256
        TX_RTU_Buffer(RTU_Status_LSB_Index) = TX_PDU_Packet.PDU_Status 'AND' &HFF
        TX_RTU_Buffer(RTU_Ref_Index) = TX_PDU_Packet.PDU_Ref
        TX_RTU_Buffer(RTU_Data_Length_Index) = TX_PDU_Packet.PDU_Data_Length

    '//----(2.2): Copy variable length data array

	Count = TX_PDU_Packet.PDU_Data_Length + 1
        RTU_Index = RTU_Data_Index
	Data_Index = 0

        While ( Count > 0 )

            TX_RTU_Buffer(RTU_Index) = TX_PDU_Packet.PDU_Data(Data_Index)

            RTU_Index = RTU_Index + 1
            Data_Index = Data_Index + 1
            Count = Count - 1

	End While

    '//----(2.3): Calculate LRC

	TX_RTU_LRC = &HAA

	While ( Count < RTU_Index )

            TX_RTU_LRC = TX_RTU_LRC + TX_RTU_Buffer(Count)
            TX_RTU_LRC = Rotate_Right(TX_RTU_LRC)

            Count = Count + 1

        End While

    '//----(2.4): Append LRC

        TX_RTU_Buffer(RTU_Index) = TX_RTU_LRC

    End Function
    '//-----------------------------------------------------------------------------------




    '//
    '//    Example Packet Contents
    '//        To             0xD0
    '//        From           0x01
    '//        Control      0x1234
    '//        Status       0x0000
    '//        Ref            0x00
    '//        Data_Length    0x00
    '//        Data(0)        0xAA
    '//
    '// Cast Packet to Buffer
    '//    Example Buffer after cast (hex dot notation)
    '//        D0.01.12.34.00.00.00.00.AA
    '//
    '//
    '// Calculate LRC
    '//
    //   Prev LRC    ADD         SUM         Rotated Value/New LRC
    //      0xAA        0xD0        0x7A        0xF4
    //	     0xF4        0x01        0xF5        0xEB
    //	     0xEB        0x12        0xFD        0xFB
    //	     0xFB        0x34        0x2F        0x5E
    //	     0x5E        0x00        0x5E        0xBC	
    //	     0xBC        0x00        0xBC        0x89
    //	     0x79        0x00        0x79        0xF2
    //	     0xF2        0x00        0xF2        0xE5
    //	     0xE5        0xAA        0x8F        0x1F
    '//
    '// Append LRC to Buffer
    '//    Example Buffer after append (hex dot notation)
    '//        D0.01.12.34.00.00.00.00.AA.1F
    '//






    '//-----------------------------------------------------------------------------------
    '//    Procedure (3): RX Buffer --> RX Packet
    '//-----------------------------------------------------------------------------------

    Function Cast_RX_RTU_Buffer_to_RX_PDU_Packet()

    '//----(3.1): Copy fixed length variables

        RX_PDU_Packet.PDU_To = RX_RTU_Buffer(RTU_To_Index)
        RX_PDU_Packet.PDU_From = RX_RTU_Buffer(RTU_From_Index)
        RX_PDU_Packet.PDU_Control = (RX_RTU_Buffer(RTU_Control_MSB_Index) * 256) "IOR" (RX_RTU_Buffer(RTU_Control_LSB_Index)) 
        RX_PDU_Packet.PDU_Status = (RX_RTU_Buffer(RTU_Status_MSB_Index) * 256) "IOR" (RX_RTU_Buffer(RTU_Status_LSB_Index)) 
        RX_PDU_Packet.PDU_Ref = RX_RTU_Buffer(RTU_Ref_Index)
        RX_PDU_Packet.PDU_Data_Length = RX_RTU_Buffer(RTU_Data_Length_Index)


    '//----(3.2): Copy variable length data array

	Index = 0

        While (Index < RX_PDU_Packet.PDU_Data_Length +1)

            RX_PDU_Packet.PDU_Data(Index) = RX_RTU_Buffer(RTU_Data_Index + Index)
            Index = Index + 1

        End While

    '//----(3.3): Calculate RX PDU LRC

	RX_PDU_LRC = &HAA

	Index = 0

        While (Index < RX_PDU_Packet.PDU_Data_Length +9)

            RX_PDU_LRC = RX_PDU_LRC + RX_RTU_Buffer(Index)
            RX_PDU_LRC = Rotate_Right(RX_PDU_LRC)

            Index = Index + 1

        End While

        RX_RTU_LRC = RX_RTU_Buffer(RTU_Data_Index + Index)

    End Function
    '//-----------------------------------------------------------------------------------
 





    '//-----------------------------------------------------------------------------------
    '//    Procedure (4): TIMS_PACKET_IO
    '//-----------------------------------------------------------------------------------

    Function TIMS_PACKET_IO()

        //----(4.1): Check for residual or unexpected receive bytes

        Get_USB_Device_Queue_Status()            // queue length returned in FT_RxQ_Bytes

            If FT_Status <> FT_OK Then
                '-- add error reporting here
                Exit Function
            End If

        //----(4.2): Read specified byte count from USB

        Read_Count = FT_RxQ_Bytes
	Read_Data_Bytes(Read_Count)              // queue returned in FT_In_Buffer(0)

            If FT_Status <> FT_OK Then
                '-- add error reporting here
                Exit Function
            End If

	Residual = FT_In_Buffer                  // copy FT_In_Buffer to Residual
 
        //----(4.3):    Transmit Packet to TIMS device

        Cast_TX_PDU_Packet_to_TX_RTU_Buffer()

	Write_Count = TX_RTU_Length              // 10 in this case

	Write_Data_Bytes(Write_Count)

            If FT_Status <> FT_OK Then
                '-- add error reporting here
                Exit Function
            End If

        //----(4.4):    Receive Packet from TIMS device

        '//----(4.4.1):  Wait till minimum 10 byte packet available in receive buffer

        Get_USB_Device_Queue_Status()

            If FT_Status <> FT_OK Then
                '-- add error reporting here
                Exit Function
            End If

        WHILE (FT_RxQ_Bytes < 10)

            Get_USB_Device_Queue_Status()

                If FT_Status <> FT_OK Then
                    '-- add error reporting here
                    Exit Function
                End If

            // place any desired timeout function here

        END WHILE


        //----(4.4.2):   Read in Header and 1st mandatory data byte, and potential LRC byte

        Read_Data_Bytes(10)

            If FT_Status <> FT_OK Then
                '-- add error reporting here
                Exit Function
            End If

        RX_Buffer_Index = 0
        In_Buffer_Index = 0

        While (RX_Buffer_Index < 10)
            RX_RTU_Buffer(RX_Buffer_Index) = FT_In_Buffer(RX_Buffer_Index)
            RX_Buffer_Index = RX_Buffer_Index + 1
        End While


        //----(4.4.3):    Check for (and read) any additional Data bytes to Read, plus LRC byte

        If (RX_RTU_Buffer(7) > 0)

            In_Buffer_Index = 0

            While (In_Buffer_Index < RX_RTU_Buffer(7))

                RX_RTU_Buffer(RX_Buffer_Index) = FT_In_Buffer(RX_Buffer_Index)
                RX_Buffer_Index = RX_Buffer_Index + 1
                In_Buffer_Index = In_Buffer_Index + 1

            End While

        End If


        //----(4.5):    Unpack header from RX_Buffer to elements

        Cast_RX_RTU_Buffer_to_RX_PDU_Packet()


        //----(4.6):    Error Checking

        If (RX_PDU_LRC <> RX_RTU_LRC)
            '// RX LRC Error reporting code goes here
        End If

        If (RX_PDU_Packet.PDU_Status <> 0)
            '// RX Status Warning or Error reporting code goes here
        End If

    End Function
    '//-----------------------------------------------------------------------------------









    '//-----------------------------------------------------------------------------------
    '//    Procedure (5): TIMS_DEVICE_CLOSE
    '//-----------------------------------------------------------------------------------

    Function TIMS_DEVICE_CLOSE()

        Close_USB_Device()

            If FT_Status <> FT_OK Then
                '-- add error reporting here
                Exit Function
            End If

    End Function
    '//-----------------------------------------------------------------------------------

